from django.db.models import Q
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.generics import ListAPIView, get_object_or_404
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework_extensions.cache.mixins import CacheResponseMixin

from custom.pagination import MyPageNumberPagination
from .serializers import *


class AreaView(ListAPIView, CacheResponseMixin):
    '''行政区规划'''
    queryset = Area.objects.all()
    serializer_class = AreasSerializer

    def get_queryset(self):
        queryset = super(AreaView, self).get_queryset()
        level = self.request.query_params.get('level', None)
        query = self.request.query_params.get('keyWord', None)

        # 当不传入其他参数时表示一级懒加载
        parent_id = self.request.query_params.get("parentId", None)
        if not level and not query:
            queryset = queryset.filter(parent_id=parent_id)

        if level:
            queryset = queryset.filter(level=level)
        if query:
            queryset = queryset.filter(Q(name__icontains=query) | Q(id__icontains=query))

        return queryset


class UserView(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    pagination_class = MyPageNumberPagination

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        # 过滤掉自己
        queryset = queryset.exclude(pk=request.user.id)

        status = self.request.query_params.get('status', None)
        query = self.request.query_params.get('keyWord', None)

        if status:
            queryset = queryset.filter(status=status)

        if query:
            queryset = queryset.filter(
                Q(username__icontains=query) |
                Q(id_card__icontains=query) |
                Q(name__icontains=query) |
                Q(email__icontains=query) |
                Q(phone__icontains=query))

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @action(methods=['get'], detail=False, url_path='doctor')
    def get_doctor(self, request):
        queryset = self.get_queryset().filter(posts__name='医生')
        dept_id = request.query_params.get('deptId', None)

        print(dept_id)
        if dept_id:
            queryset = queryset.filter(dept__id=dept_id)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @action(methods=['POST'], detail=False, url_path='check')
    def check(self, request, *args, **kwargs):
        """
        检查信息是否重复
        """
        id_card = request.data.get('id_card')
        if id_card and User.objects.filter(id_card=id_card).exists():
            return Response(status=status.HTTP_406_NOT_ACCEPTABLE)
        phone = request.data.get('phone')
        if phone and User.objects.filter(phone=phone).exists():
            return Response(status=status.HTTP_406_NOT_ACCEPTABLE)

        user_id = request.data.get('id')
        username = request.data.get('username')
        if username and user_id and User.objects.exclude(id=user_id).filter(username=username).exists():
            return Response(status=status.HTTP_406_NOT_ACCEPTABLE)

        return Response(status=status.HTTP_202_ACCEPTED)

    @action(methods=['GET'], detail=False, url_path='info')
    def info(self, request, *args, **kwargs):
        """
        获取用户信息
        """
        serializer = UserInfoSerializer(instance=request.user)

        # print(serializer.data)
        return Response(serializer.data)
        # return Response(request.user.get_user_info())

    @swagger_auto_schema(request_body=openapi.Schema(
        description='不传值表示重置密码为123456',
        type=openapi.TYPE_OBJECT,
        # required=[],
        properties={
            'new_password': openapi.Schema(type=openapi.TYPE_STRING),
            'old_password': openapi.Schema(type=openapi.TYPE_STRING),
        }),
        operation_summary='修改或重置密码')
    @action(methods=['POST'], detail=True, url_path='setpwd')
    def set_password(self, request, *args, **kwargs):
        """修改或重置密码"""
        user = get_object_or_404(self.get_queryset(), id=request.data.pop('id', None))
        serializer = ResetPasswordSerializer(user, request.data)

        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(user, '_prefetched_objects_cache', None):
            user._prefetched_objects_cache = {}

        return Response(status=status.HTTP_200_OK)


class RoleView(ModelViewSet):
    queryset = Role.objects.all()
    serializer_class = RoleSerializer

    @action(methods=['GET'], detail=False, url_path='options')
    def get_options(self, request):
        queryset = self.get_queryset()
        serializer = RoleOptionsSerializer(queryset, many=True)
        data = serializer.data
        return Response(data=data)

    # @action(methods=['GET'], detail=False, url_path='options')
    # def test


class MenuViewSet(ModelViewSet):
    """
    菜单管理接口
    """
    queryset = Menu.objects.all()
    serializer_class = MenuSerializer

    @action(methods=['GET'], detail=False,url_path='router', permission_classes=[])
    def get_router(self, request):
        """用于前端获取当前角色的路由"""
        user = request.user
        queryset = self.queryset.filter(status=True, menu_type__lt=2, parent__isnull=True)
        menu_ids = user.roles.filter(status=True).values_list('menus__id', flat=True)
        if not user.is_superuser:
            queryset = queryset.filter(id__in=menu_ids)
            # print(menu_ids)

        serializer = WebRouterSerializer(queryset, many=True, context={'user': user,'menu_ids':menu_ids})
        return Response(data=serializer.data)

    @action(methods=['GET'], detail=False, url_path='options')
    def get_options(self, request):
        queryset = self.queryset.filter(status=True, menu_type__lt=2)

        menu_type = self.request.query_params.get('menuType', None)
        if menu_type is not None:
            queryset = queryset.filter(menu_type__exact=menu_type)

        serializer = MenuOptionsSerializer(queryset, many=True)
        data = serializer.data
        return Response(data=data)

    @action(methods=['GET'], detail=False, url_path='lazy')
    def lazy(self, request):
        """懒加载"""
        queryset = self.get_queryset()
        parent_id = request.query_params.get("parentId", None)
        queryset = queryset.filter(parent_id=parent_id)
        serializer = self.get_serializer(queryset, many=True)

        return Response(data=serializer.data)

    @action(methods=['GET'], detail=False, url_path='permissions')
    def get_permission_list(self, request):
        """获取权限列表"""
        queryset = self.get_queryset()

        queryset = queryset.filter(status=True, parent__isnull=True)
        serializer = PermissionListSerializer(queryset, many=True)
        data = serializer.data
        return Response(data=data)


class DeptViewSet(ModelViewSet):
    """
    部门管理接口
    """
    queryset = Dept.objects.all()
    serializer_class = DeptSerializer

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        dept_type = self.request.query_params.get('deptType', None)
        if dept_type:
            queryset = queryset.filter(dept_type=dept_type)

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    @action(methods=['GET'], detail=False, url_path='options')
    def get_options(self, request):
        queryset = self.get_queryset()

        # 部门管理上级部门，暂时返回一级目录
        queryset = queryset.filter(status=True)

        serializer = DeptOptionsSerializer(queryset, many=True)
        data = serializer.data
        return Response(data=data)

    @action(methods=['get'], detail=False, url_path='schools')
    def get_schools(self, request):
        """获取学校列表"""
        queryset = self.get_queryset()
        queryset = queryset.filter(dept_type=0, status=True)
        # serializer = self.get_serializer(queryset, many=True)
        serializer = DeptOptionsSerializer(queryset, many=True)
        return Response(serializer.data)

    @action(methods=['get'], detail=False, url_path='hospitals')
    def get_hospitals(self, request):
        """获取医院列表"""
        queryset = self.get_queryset()
        queryset = queryset.filter(dept_type=1, status=True)
        serializer = DeptOptionsSerializer(queryset, many=True)
        return Response(serializer.data)


class PostView(ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

    @action(methods=['GET'], detail=False, url_path='options')
    def get_options(self, request):
        queryset = self.get_queryset()
        serializer = PostOptionsSerializer(queryset, many=True)
        data = serializer.data
        return Response(data=data)


class LoginLogView(ModelViewSet):
    """
    登录日志接口
    """
    queryset = LoginLog.objects.all()
    serializer_class = LoginLogSerializer
    pagination_class = MyPageNumberPagination


class OperationLogView(ModelViewSet):
    """
    操作日志接口
    """
    queryset = OperationLog.objects.order_by('-create_time')
    serializer_class = OperationLogSerializer
    pagination_class = MyPageNumberPagination


class DictionaryView(ModelViewSet):
    queryset = Dictionary.objects.all()
    serializer_class = DictionarySerializer

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        # 不传parentId值时获取非值字典
        parent_id = self.request.query_params.get('parentId', None)
        queryset = queryset.filter(parent=parent_id)

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
